<?php
class db {
	var $connection_id = "";
	var $pconnect = 0;
	var $shutdown_queries = array();
	var $queries = array();
	var $query_id = "";
	var $query_count = 0;
	var $record_row = array();
	var $return_die = 0;
	var $failed = 0;
	var $halt = "";

	var $query_log = array();

	function connect($db_config){
		if ($this->pconnect){
			$this->connection_id = mysql_pconnect( $db_config["hostname"], $db_config["username"], $db_config["password"] );
		}else{
			$this->connection_id = mysql_connect( $db_config["hostname"], $db_config["username"], $db_config["password"] );
		}
		if ( ! $this->connection_id ){
			$this->halt("Can not connect MySQL Server");
		}
		if ( ! @mysql_select_db($db_config["database"], $this->connection_id) ){
			$this->halt("Can not connect MySQL Database");
		}
		if ($db_config["charset"]) {
			@mysql_unbuffered_query("SET NAMES '".$db_config["charset"]."'");
		}
		return TRUE;
	}
	//发送SQL 查询，并返回结果集
    function query($query_id, $query_type='mysql_query'){
		if (DEBUG) {
			$str = '<pre><br/>Query' . ($query_type == 'mysql_unbuffered_query' ? ' (UNBUFFERED)' : '') . ":\n" . htmlspecialchars($query_id) . "\n";
			global $pagestarttime;
			$pageendtime = microtime();
			$starttime = explode(' ', $pagestarttime);
			$endtime = explode(' ', $pageendtime);
			$beforetime = $endtime[0] - $starttime[0] + $endtime[1] - $starttime[1];
			$str.= "Time before: $beforetime<br/>";
			if (function_exists('memory_get_usage')) {
				$str.= "Memory Before: " . number_format((memory_get_usage() / 1024)) . 'KB' . " <br/></pre>";
			}
		}

        $this->query_id = $query_type($query_id, $this->connection_id);
		$this->queries[] = $query_id;
        if (! $this->query_id ) {
            $this->halt("查询失败:\n$query_id");
		}
		$this->query_count++;


		if (DEBUG) {
			$pageendtime = microtime();
			$starttime = explode(' ', $pagestarttime);
			$endtime = explode(' ', $pageendtime);
			$aftertime = $endtime[0] - $starttime[0] + $endtime[1] - $starttime[1];
			$querytime += $aftertime - $beforetime;
			$str.= "Time after: $aftertime\n";
			$str.= "Time taken: " . ($aftertime - $beforetime) . "\n";
			if (function_exists('memory_get_usage')) {
				$str.= "Memory After: " . number_format((memory_get_usage() / 1024)) . 'KB' . " \n";
			}
			if (DEBUG AND preg_match('#(^|\s)SELECT\s+#si', $query_id)) {
				$explain_id = mysql_query("EXPLAIN " . $query_id, $this->connection_id);
				$str.= "</pre>\n";
				$str.= '
				<table width="80%" border="1" style="border-collapse:collapse" cellpadding="0" cellspacing="0" bordercolor="#000000" align="center">
				<tr height="25" style="font-weight:bold">
					<td>table</td>
					<td>type</td>
					<td>possible_keys</td>
					<td>key</td>
					<td>key_len</td>
					<td>ref</td>
					<td>rows</td>
					<td>Extra</td>
				</tr>
				';
				$str_tmp = "";
				while($array = mysql_fetch_assoc($explain_id)) {
					$str_tmp.= "
					<tr height='25'>
						<td>$array[table]&nbsp;</td>
						<td>$array[type]&nbsp;</td>
						<td>$array[possible_keys]&nbsp;</td>
						<td>$array[key]&nbsp;</td>
						<td>$array[key_len]&nbsp;</td>
						<td>$array[ref]&nbsp;</td>
						<td>$array[rows]&nbsp;</td>
						<td>$array[Extra]&nbsp;</td>
					</tr>
					";
				}
				$str.= $str_tmp."</table>\n<br /><hr width='80%' />\n";
				$str.= "\n<pre>";
			} else {
				$str.= "\n<hr width='80%' />\n\n";
			}
		}
		$this->query_log[] = $str;
        return $this->query_id;

    }
	//发送SQL 查询，并不获取和缓存结果的行
	function query_unbuffered($query_id = ""){
		return $this->query($query_id, 'mysql_unbuffered_query');
	}
	//从结果集中取得一行作为关联数组
    function fetch_array($query_id = ""){
    	if ($query_id == "") $query_id = $this->query_id;
        $this->record_row = @mysql_fetch_array($query_id, MYSQL_ASSOC);
        return $this->record_row;
    }
	//取得 第一行 作为关联数组
	function query_first($query_id = ""){
		$query_id = $this->query($query_id);
		$returnarray = $this->fetch_array($query_id);
		$this->free_result($query_id);
		return $returnarray;
	}

	function shutdown_query($query_id = ""){
		$this->shutdown_queries[] = $query_id;
    }
	//取得结果集中行的数目，仅对 INSERT，UPDATE 或者 DELETE
	function affected_rows() {
        return @mysql_affected_rows($this->connection_id);
    }
	//取得结果集中行的数目，仅对 SELECT 语句有效
    function num_rows($query_id="") {
		if ($query_id == "") $query_id = $this->query_id;
        return @mysql_num_rows($query_id);
    }
	//返回上一个 MySQL 操作中的错误信息的数字编码
	function geterrno(){
		$this->errno = @mysql_errno($this->connection_id);
		return $this->errno;
	}
	//取得上一步 INSERT 操作产生的 ID
    function insert_id(){
        return @mysql_insert_id($this->connection_id);
    }
	//得到查询次数
    function query_count() {
        return $this->query_count;
    }
	//释放结果内存
    function free_result($query_id="")
	{
   		if ($query_id == "") $query_id = $this->query_id;
    	@mysql_free_result($query_id);
    }
	//关闭 MySQL 连接
    function close_db(){
    	if ( $this->connection_id ) return @mysql_close( $this->connection_id );
    }
	//列出 MySQL 数据库中的表
    function get_table_names(){
    	global $db_config;
		$result = mysql_list_tables($db_config["database"]);
		$num_tables = @mysql_numrows($result);
		for ($i = 0; $i < $num_tables; $i++) {
			$tables[] = mysql_tablename($result, $i);
		}
		mysql_free_result($result);
		return $tables;
   	}
	//从结果集中取得列信息并作为对象返回，取得所有字段
    function get_result_fields($query_id=""){
   		if ($query_id == "") $query_id = $this->query_id;
		while ($field = mysql_fetch_field($query_id)) {
            $fields[] = $field;
		}
		return $fields;
   	}
	//错误提示
    function halt($the_error=""){
		$this->error = @mysql_error($this->connection_id);
		$message = $the_error."<br/>\r\n";
		$message.= $this->error . "<br/>\r\n";

		$sql = "INSERT INTO `db_error`(pagename, errstr, timer) VALUES('".$_SERVER["PHP_SELF"]."', '".addslashes($message)."', ".time().")";
		@mysql_unbuffered_query($sql);

		if (DEBUG){
			echo "<html><head><title>MySQL 数据库错误</title>";
			echo "<style type=\"text/css\"><!--.error { font: 11px tahoma, verdana, arial, sans-serif, simsun; }--></style></head>\r\n";
			echo "<body>\r\n";
			echo "<blockquote>\r\n";
			echo "<textarea class=\"error\" rows=\"15\" cols=\"100\" wrap=\"on\" >" . htmlspecialchars($message) . "</textarea>\r\n";
			echo "</blockquote>\r\n</body></html>";
			exit;
		}
    }
	function __destruct(){
		$this->close_db();
	}
	function sql_select($tbname, $where="", $limit="", $fields="*", $orderby="id", $sort="DESC"){
		$sql = "SELECT ".$fields." FROM `".$tbname."` ".($where?" WHERE ".$where:"")." ORDER BY ".$orderby." ".$sort.($limit ? " limit ".$limit:"");
		return $sql;
	}
	function sql_insert($tbname, $row){
		foreach ($row as $key=>$value) {
			$sqlfield .= $key.",";
			$sqlvalue .= "'".$value."',";
		}
		return "INSERT INTO `".$tbname."`(".substr($sqlfield, 0, -1).") VALUES (".substr($sqlvalue, 0, -1).")";
	}
	function sql_update($tbname, $row, $where){
		foreach ($row as $key=>$value) {
			$sqlud .= $key."= '".$value."',";
		}
		return "UPDATE `".$tbname."` SET ".substr($sqlud, 0, -1)." WHERE ".$where;
	}
	function sql_delete($tbname, $where){
		return "DELETE FROM `".$tbname."` WHERE ".$where;
	}

	//新增加一条记录
	function row_insert($tbname, $row){
		$sql = $this->sql_insert($tbname, $row);
		return $this->query_unbuffered($sql);
	}

	//更新指定记录
	function row_update($tbname, $row, $where){
		$sql = $this->sql_update($tbname, $row, $where);
		return $this->query_unbuffered($sql);
	}

	//删除满足条件的记录
	function row_delete($tbname, $where){
		$sql = $this->sql_delete($tbname, $where);
		return $this->query_unbuffered($sql);
	}

	/*	根据条件查询，返回所有记录
	 *	$tbname 表名, $where 查询条件, $limit 返回记录, $fields 返回字段
	 */
	function row_select($tbname, $where="", $limit="", $fields="*", $orderby="id", $sort="DESC"){
		$sql = $this->sql_select($tbname, $where, $limit, $fields, $orderby, $sort);
		//echo $sql;
		return $this->row_query($sql);
	}

	//详细显示一条记录
	function row_select_one($tbname, $where, $fields="*", $orderby="id"){
		$sql = $this->sql_select($tbname, $where, 1, $fields, $orderby);
		return $this->row_query_one($sql);
	}
	function row_query($sql){
		$rs	 = $this->query($sql);
		$rs_num = $this->num_rows($rs);
		$rows = array();
		for($i=0; $i<$rs_num; $i++){
			$rows[] = $this->fetch_array($rs);
		}
		$this->free_result($rs);
		return $rows;
	}
	function row_query_one($sql){
		$rs	 = $this->query($sql);
		$row = $this->fetch_array($rs);
		$this->free_result($rs);
		return $row;
	}

	//计数统计
	function row_count($tbname, $where=""){
		$sql = "SELECT count(id) as row_sum FROM `".$tbname."` ".($where?" WHERE ".$where:"");
		$row = $this->row_query_one($sql);
		return $row["row_sum"];
	}
}
?>
